package com.piece.core.jpa.repository;

import com.piece.core.framework.enums.StatusType;
import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.util.object.BeanUtil;
import com.piece.core.framework.util.object.ClassUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 通用service层
 */
@Slf4j
public class BaseService<T, ID extends Serializable> {

    protected IBaseRepository repository;

    protected void setRepository(IBaseRepository repository) {
        this.repository = repository;
    }

    /**
     * 插入或更新
     */
    public T insertOrUpdate(T entity) throws Exception {
        Object key = BeanUtil.getKeyValue(entity);
        if (ClassUtil.isEmpty(key)) {
            return insert(entity);
        }
        update(entity);
        return entity;
    }

    /**
     * 插入记录
     */
    public T insert(T entity) throws Exception {
        return (T) repository.insert(entity);
    }

    /**
     * 批量插入
     */
    public List<T> batchInsert(List<T> list) throws Exception {
        return repository.batchInsert(list);
    }

    /**
     * 更新记录
     */
    public void update(T entity) throws Exception {
        repository.update(entity);
    }

    /**
     * 批量更新
     */
    public void batchUpdate(List<T> list) throws Exception {
        repository.batchUpdate(list);
    }

    /**
     * 更新非空属性记录
     */
    public void updateNotNull(T entity) throws Exception {
        repository.updateNotNull(entity);
    }

    /**
     * 删除记录
     */
    public void delete(T entity) throws Exception {
        repository.delete(entity);
    }

    /**
     * 批量删除
     */
    public void batchDelete(List<T> list) throws Exception {
        repository.batchDelete(list);
    }

    /**
     * 删除记录
     */
    public void delete(Serializable id) throws Exception {
        repository.delete(id);
    }

    /**
     * 删除记录
     */
    public int delete(Serializable[] ids) throws Exception {
        return repository.delete(ids);
    }

    /**
     * 根据id查询单条记录
     */
    public T findById(Serializable id) {
        return (T) repository.findById(id);
    }

    /**
     * 根据条件查询单条记录
     *
     * @param condition 查询条件
     */
    public T findOneByCondition(Map<String, Object> condition) {
        return (T) repository.findOneByCondition(condition);
    }

    /**
     * 根据条件查询单条记录
     *
     * @param condition 查询条件
     */
    public List<T> findByCondition(Map<String, Object> condition) {
        return repository.findByCondition(condition, generateDefaultOrder());
    }

    /**
     * 根据条件查询单条记录
     *
     * @param entity 查询条件
     */
    public List<T> findByConditionWithEntity(T entity, List<Order> orders) {
        return repository.findByConditionWithEntity(entity, orders);
    }

    /**
     * 根据条件查询单条记录
     *
     * @param condition 查询条件
     */
    public List<T> findByCondition(Map<String, Object> condition, List<Order> orders) {
        return repository.findByCondition(condition, orders);
    }

    /**
     * 分页查询
     *
     * @param queryTable 查询条件
     */
    public DataTable<T> findPage(QueryTable queryTable) {
        return repository.findPage(queryTable);
    }

    /**
     * 分组统计查询
     *
     * @param queryTable  查询条件
     * @param targetClass 分组结果类型
     */
    public List findGroup(QueryTable queryTable, Class targetClass) {
        return repository.findByGroup(queryTable, targetClass);
    }

    /**
     * 查询所有
     */
    public List<T> findAll() {
        if (BeanUtil.hasField(repository.getEntityClass(), "status")) {
            return repository.findByCondition("status", StatusType.SUCCESS.getCode(), generateDefaultOrder());
        }
        return repository.findAll();
    }

    /**
     * 查询所有
     */
    public List<T> findAllWithOutStatus() {
        return repository.findAll();
    }

    public List<T> findByHql(String hql, Object[] params) {
        return repository.find(hql, params);
    }

    public boolean checkExist(Serializable id) {
        return repository.checkExist(id);
    }

    public boolean checkExist(List<Serializable> ids) {
        return repository.checkExist(ids.toArray());
    }

    public void flush() {
        repository.flush();
    }

    public void clear() {
        repository.clear();
    }

    protected List<Order> generateDefaultOrder() {
        return null;
    }
}